home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / HENSA / MATHS / PLPLOT / PLPLOT.ZIP / sys / amiga / old / plsupport. < prev    next >
Encoding:
Text File  |  1993-03-16  |  18.0 KB  |  778 lines

  1. /* $Id: plsupport.c,v 1.1 1993/03/15 21:30:58 mjl Exp $
  2.    $Log: plsupport.c,v $
  3.  * Revision 1.1  1993/03/15  21:30:58  mjl
  4.  * Files shuffled around in the Amiga driver reorganization.
  5.  *
  6.  * Revision 1.2  1992/10/12  17:11:27  mjl
  7.  * Amiga-specific mods, including ANSI-fication.
  8.  *
  9.  * Revision 1.1  1992/05/20  21:35:29  furnish
  10.  * Initial checkin of the whole PLPLOT project.
  11.  *
  12. */
  13.  
  14. #include "plplot.h"
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18.  
  19. #include "plamiga.h"
  20. #include <libraries/dosextens.h>
  21.  
  22. extern short fbuffer;
  23. extern FILE *PlotFile;
  24.  
  25. /* Most of the IFF and preferences stuff borrowed from Tom Rokicki */
  26. static union printerIO {
  27.     struct IOStdReq ios;
  28.     struct IODRPReq iodrp;
  29.     struct IOPrtCmdReq iopc;
  30. } *printerIO;
  31.  
  32. static struct PrinterData *PD;
  33. static struct PrinterExtendedData *PED;
  34. static struct MsgPort *replyport;
  35. static struct RastPort rastport;
  36. static struct BitMap Bitmap;
  37. static short dummycolors[] =
  38. {0x0000, 0x0fff};
  39. static struct ColorMap dummyColorMap =
  40. {NULL, NULL, 2, (APTR) & dummycolors};
  41.  
  42.  
  43. static void 
  44. doio(void)
  45. {
  46.     register struct IODRPReq *ioreq;
  47.  
  48.     ioreq = &printerIO->iodrp;
  49.     SendIO((struct IORequest *) ioreq);
  50.     while (1) {
  51.     if (GetMsg(replyport) == NULL)
  52.         Wait(1L << replyport->mp_SigBit);
  53.     else
  54.         break;
  55.     }
  56. }
  57.  
  58. void 
  59. dmpport(long flags, int x, int y)
  60. {
  61.     register struct IODRPReq *ioreq;
  62.  
  63.     ioreq = &printerIO->iodrp;
  64.     ioreq->io_Command = PRD_DUMPRPORT;
  65.     ioreq->io_RastPort = &rastport;
  66.     ioreq->io_ColorMap = &dummyColorMap;
  67.     ioreq->io_Modes = 0;
  68.     ioreq->io_SrcX = 0;
  69.     ioreq->io_SrcY = 0;
  70.     ioreq->io_SrcWidth = x;
  71.     ioreq->io_SrcHeight = y;
  72.     ioreq->io_DestCols = x;
  73.     ioreq->io_DestRows = y;
  74.     ioreq->io_Special = flags | SPECIAL_TRUSTME;
  75.     doio();
  76. }
  77.  
  78. static long bitmapx, bitmapy, wordsperrow;
  79. static short *bitmap;
  80.  
  81. int 
  82. mapinit(long bmapx, long bmapy)
  83. {
  84.     bitmapx = bmapx;
  85.     bitmapy = bmapy;
  86.     wordsperrow = (bmapx + 15) / 16;
  87.     Bitmap.BytesPerRow = wordsperrow * 2;
  88.     Bitmap.Rows = bmapy;
  89.     /* Allocate memory for bitmap */
  90.     if ((bitmap = (short *) calloc(wordsperrow * 2, (int) bmapy)) == NULL) {
  91.     fprintf(stderr, "\nCan't allocate memory for bitmap dump.\n");
  92.     return (1);
  93.     }
  94.     Bitmap.Planes[0] = (PLANEPTR) bitmap;
  95.     return (0);
  96. }
  97.  
  98. void 
  99. mapfree(void)
  100. {
  101.     free((VOID *) bitmap);
  102. }
  103.  
  104. void 
  105. mapclear(void)
  106. {
  107.     memset((char *) bitmap, '\0', (int) (wordsperrow * (long) bitmapy * 2));
  108. }
  109.  
  110. /* Function to draw the line in the bitmap */
  111.  
  112. void 
  113. mapline(register int x1, register int y1, register int x2, register int y2)
  114. {
  115.     register short *p;
  116.     register unsigned int b;
  117.     register int t;
  118.     int d;
  119.     int nextrow;
  120.  
  121.     /* we always want to go left to right. */
  122.     if (x1 > x2) {
  123.     t = x1;
  124.     x1 = x2;
  125.     x2 = t;
  126.     t = y1;
  127.     y1 = y2;
  128.     y2 = t;
  129.     }
  130.     p = bitmap + y1 * wordsperrow;
  131.     /* we always want to go `up'. */
  132.     if (y2 > y1)
  133.     nextrow = wordsperrow;
  134.     else {
  135.     y2 = y1 * 2 - y2;
  136.     nextrow = -wordsperrow;
  137.     }
  138.     b = 1L << (15 - (x1 & 15));
  139.     p += (x1 >> 4);
  140.     x2 -= x1;
  141.     y2 -= y1;
  142.     /* two routines, one for major in x, one for major in y */
  143.     if (y2 > x2) {
  144.     d = y2;
  145.     t = x2 / 2;
  146.     y1 = y2;
  147.     while (y1 >= 0) {
  148.         *p |= b;
  149.         p += nextrow;
  150.         t += x2;
  151.         if (t >= d) {
  152.         t -= d;
  153.         b >>= 1;
  154.         if (b == 0) {
  155.             b = 0x8000;
  156.             p++;
  157.         }
  158.         }
  159.         y1--;
  160.     }
  161.     }
  162.     else {
  163.     d = x2;
  164.     t = y2 / 2;
  165.     x1 = x2;
  166.     while (x1 >= 0) {
  167.         *p |= b;
  168.         b >>= 1;
  169.         if (b == 0) {
  170.         b = 0x8000;
  171.         p++;
  172.         }
  173.         t += y2;
  174.         if (t >= d) {
  175.         t -= d;
  176.         p += nextrow;
  177.         }
  178.         x1--;
  179.     }
  180.     }
  181. }
  182.  
  183. int 
  184. openprinter(void)
  185. {
  186.     replyport = (struct MsgPort *) CreatePort("PLPlot.PIO", 0L);
  187.     if (replyport == NULL) {
  188.     fprintf(stderr, "Couldn't open reply port for printer dump.\n");
  189.     return (1);
  190.     }
  191.  
  192.     printerIO = (union printerIO *)
  193.     AllocMem((long) sizeof(union printerIO),
  194.          (long) (MEMF_CLEAR | MEMF_PUBLIC));
  195.     if (printerIO == NULL) {
  196.     DeletePort(replyport);
  197.     fprintf(stderr, "Couldn't create IO request block for printer dump.\n");
  198.     return (1);
  199.     }
  200.     printerIO->ios.io_Message.mn_Node.ln_Type = NT_MESSAGE;
  201.     printerIO->ios.io_Message.mn_Length = sizeof(union printerIO);
  202.     printerIO->ios.io_Message.mn_ReplyPort = replyport;
  203.  
  204.     if (OpenDevice("printer.device", 0L, (struct IORequest *) printerIO, 0L) != NULL) {
  205.     FreeMem((VOID *) printerIO, (long) sizeof(union printerIO));
  206.     DeletePort(replyport);
  207.     fprintf(stderr, "Error opening printer device.\n");
  208.     return (1);
  209.     }
  210.  
  211.     PD = (struct PrinterData *) printerIO->iodrp.io_Device;
  212.     PED = &PD->pd_SegmentData->ps_PED;
  213.     return (0);
  214. }
  215.  
  216. void 
  217. closeprinter(void)
  218. {
  219.     CloseDevice((struct IORequest *) printerIO);
  220.     FreeMem((VOID *) printerIO, (long) sizeof(union printerIO));
  221.     DeletePort(replyport);
  222. }
  223.  
  224. int 
  225. queryprint(long *bmapx, long *bmapy, long *bmapxmax, long *bmapymax, 
  226.        long *xdpi, long *ydpi)
  227. {
  228.     int mode;
  229.     Bitmap.BytesPerRow = 0;
  230.     Bitmap.Rows = 0;
  231.     Bitmap.Depth = 1;
  232.     rastport.BitMap = &Bitmap;
  233.     dmpport((long) (SPECIAL_NOPRINT), 0, 0);
  234.  
  235.     *bmapxmax = PED->ped_MaxXDots;
  236.     *bmapymax = 95 * PED->ped_YDotsInch / 10;    /* 9.5" to prevent problems */
  237.  
  238.     *xdpi = PED->ped_XDotsInch;
  239.     *ydpi = PED->ped_YDotsInch;
  240.  
  241.     if (PD->pd_Preferences.PrintFlags & BOUNDED_DIMENSIONS) {
  242.     *bmapx = PD->pd_Preferences.PrintMaxWidth * PED->ped_XDotsInch / 10;
  243.     *bmapy = PD->pd_Preferences.PrintMaxHeight * PED->ped_YDotsInch / 10;
  244.     mode = 1;
  245.     }
  246.     else if (PD->pd_Preferences.PrintFlags & ABSOLUTE_DIMENSIONS) {
  247.     *bmapx = PD->pd_Preferences.PrintMaxWidth * PED->ped_XDotsInch / 10;
  248.     *bmapy = PD->pd_Preferences.PrintMaxHeight * PED->ped_YDotsInch / 10;
  249.     mode = 0;
  250.     }
  251.     else if (PD->pd_Preferences.PrintFlags & PIXEL_DIMENSIONS) {
  252.     *bmapx = PD->pd_Preferences.PrintMaxWidth;
  253.     *bmapy = PD->pd_Preferences.PrintMaxHeight;
  254.     mode = 0;
  255.     }
  256.     else {
  257.     *bmapx = *bmapxmax;
  258.     *bmapy = *bmapymax;
  259.     mode = 1;
  260.     }
  261.  
  262.     PD->pd_Preferences.PrintImage = IMAGE_NEGATIVE;
  263.     PD->pd_Preferences.PrintShade = SHADE_BW;
  264.     PD->pd_Preferences.PrintThreshold = 7;
  265.     PD->pd_Preferences.PrintAspect = ASPECT_HORIZ;
  266.     PD->pd_Preferences.PrintFlags = INTEGER_SCALING;
  267.     return (mode);
  268. }
  269.  
  270. void 
  271. ejectpage(void)
  272. {
  273.     printerIO->ios.io_Command = PRD_RAWWRITE;
  274.     printerIO->ios.io_Data = (APTR) "\014";
  275.     printerIO->ios.io_Length = 1;
  276.     doio();
  277. }
  278.  
  279. /* If type = 0 dump the plplot window to the printer with full preferences
  280.    support, i.e. color, shading, threshold, etc.  Otherwise we override many
  281.    of the preferences selections, create a full page black and white
  282.    bitmap and dump it to the printer. */
  283.  
  284. void 
  285. screendump(PLINT type)
  286. {
  287.     register struct IODRPReq *ioreq;
  288.     long bmapx, bmapy;
  289.     long cxy, x1, y1;
  290.     long dwidth, dheight, xlas, ylas, xnew, ynew;
  291.     int penwid = 1;
  292.  
  293.     if (type != 0 && fbuffer == 0)
  294.     return;
  295.     if (openprinter())        /* return if error */
  296.     return;
  297.  
  298.     ioreq = &printerIO->iodrp;
  299.  
  300.     if (type == 0) {
  301.     ioreq->io_Command = PRD_DUMPRPORT;
  302.     ioreq->io_RastPort = PLWRPort;
  303.     ioreq->io_ColorMap = PLScreen->ViewPort.ColorMap;
  304.     ioreq->io_Modes = PLScreen->ViewPort.Modes;
  305.     ioreq->io_SrcX = XOffset;
  306.     ioreq->io_SrcY = YOffset;
  307.     ioreq->io_SrcWidth = PLWidth;
  308.     ioreq->io_SrcHeight = PLHeight;
  309.     ioreq->io_DestCols = 0;
  310.     ioreq->io_DestRows = 0;
  311.     ioreq->io_Special = SPECIAL_FULLROWS | SPECIAL_FULLCOLS |
  312.         SPECIAL_TRUSTME;
  313.     doio();
  314.     }
  315.     else {
  316.     /* get bmapx and bmapy (the others are dummy variables) */
  317.     queryprint(&bmapx, &bmapy, &dwidth, &dheight, &dwidth, &dheight);
  318.  
  319.     /* Set up map */
  320.     if (mapinit(bmapx, bmapy)) {
  321.         closeprinter();
  322.         return;
  323.     }
  324.  
  325.     prepupdate();
  326.  
  327.     dwidth = bmapx - 2;
  328.     dheight = bmapy - 2;
  329.     while (!getpoint(&cxy, &x1, &y1)) {
  330.         if (cxy == PENU) {
  331.         if (type == 1) {
  332.             xlas = ((long) dheight * (long) x1) / InitPLWidth;
  333.             ylas = ((long) dwidth * (long) y1) / InitPLHeight;
  334.         }
  335.         else {
  336.             xlas = ((long) dwidth * (long) x1) / InitPLWidth;
  337.             ylas = ((long) dheight * (long) y1) / InitPLHeight;
  338.         }
  339.         }
  340.         else if (cxy == PEND) {
  341.         if (type == 1) {
  342.             xnew = ((long) dheight * (long) x1) / InitPLWidth;
  343.             ynew = ((long) dwidth * (long) y1) / InitPLHeight;
  344.             switch (penwid) {
  345.             case 3:
  346.               mapline(ylas, xlas, ynew, xnew);
  347.             case 2:
  348.               mapline(ylas + 2, xlas + 2, ynew + 2, xnew + 2);
  349.             case 1:
  350.             default:
  351.               mapline(ylas + 1, xlas + 1, ynew + 1, xnew + 1);
  352.             }
  353.         }
  354.         else {
  355.             xnew = ((long) dwidth * (long) x1) / InitPLWidth;
  356.             ynew = ((long) dheight * (long) y1) / InitPLHeight;
  357.             switch (penwid) {
  358.             case 3:
  359.               mapline(xlas, dheight - ylas, xnew, dheight - ynew);
  360.             case 2:
  361.               mapline(xlas + 2, dheight - ylas + 2, xnew + 1, dheight - ynew + 2);
  362.             case 1:
  363.             default:
  364.               mapline(xlas + 1, dheight - ylas + 1, xnew + 1, dheight - ynew + 1);
  365.             }
  366.         }
  367.         xlas = xnew;
  368.         ylas = ynew;
  369.         }
  370.         else if (cxy == SPEN) {
  371.         ;
  372.         }
  373.         else if (cxy == PWID) {
  374.         penwid = x1;
  375.         }
  376.     }
  377.     finiupdate();
  378.  
  379.     dmpport(0L, bmapx, bmapy);
  380.     mapfree();
  381.     }
  382.     closeprinter();
  383. }
  384.  
  385. /* prepupdate() flushes and rewinds the plot buffer file.  This should always
  386.    be called before attempting to read the buffer file. */
  387.  
  388. void 
  389. prepupdate(void)
  390. {
  391. /*    plgfile(PlotFile); */
  392.     if (fbuffer) {
  393.     fflush(PlotFile);
  394.     rewind(PlotFile);
  395.     }
  396. }
  397.  
  398. /* Use getpoint to read the next command in the plot buffer file. */
  399. /* Returns 0 if okay or 1 if end of file. */
  400.  
  401. int 
  402. getpoint(long *com, long *x, long *y)
  403. {
  404.     short csh, xsh, ysh;
  405.  
  406. /*    plgfile(PlotFile); */
  407.     if (!fread((char *) &csh, sizeof(short), 1, PlotFile))
  408.     return (1);
  409.  
  410.     *com = csh;
  411.     if (csh == PENU || csh == PEND) {
  412.     fread((char *) &xsh, sizeof(short), 1, PlotFile);
  413.     fread((char *) &ysh, sizeof(short), 1, PlotFile);
  414.     *x = xsh;
  415.     *y = ysh;
  416.     }
  417.     else if (csh == SPEN || csh == PWID) {
  418.     fread((char *) &xsh, sizeof(short), 1, PlotFile);
  419.     *x = xsh;
  420.     }
  421.  
  422.     return (0);
  423. }
  424.  
  425. void 
  426. finiupdate(void)
  427. {
  428. /*    plgfile(PlotFile); */
  429.     fseek(PlotFile, 0L, 2);
  430. }
  431.  
  432. static long iffpos;
  433. static short curbyte;
  434. static short curcount;
  435. static short runcount;
  436. static FILE *OutFile;
  437.  
  438. struct BitMapHeader {
  439.     UWORD w, h;
  440.     WORD x, y;
  441.     UBYTE nPlanes;
  442.     UBYTE masking;
  443.     UBYTE compression;
  444.     UBYTE pad1;
  445.     UWORD transparentColor;
  446.     UBYTE xAspect, yAspect;
  447.     WORD pageWidth, pageHeight;
  448. } bmhd;
  449.  
  450. static void 
  451. iffobyte(register int b)
  452. {
  453.     putc(b, OutFile);
  454.     iffpos++;
  455. }
  456. char outchunk[256];
  457.  
  458. static void 
  459. iffoutbyte(register int b)
  460. {
  461.     register int i;
  462.  
  463.     if (b == curbyte && runcount < 125) {
  464.     runcount++;
  465.     }
  466.     else {
  467.     if (runcount > 2) {
  468.         if (curcount > 0) {
  469.         iffobyte(curcount - 1);
  470.         for (i = 0; i < curcount; i++)
  471.             iffobyte(outchunk[i]);
  472.         curcount = 0;
  473.         }
  474.         iffobyte(256 - runcount + 1);
  475.         iffobyte(curbyte);
  476.     }
  477.     else {
  478.         while (runcount > 0) {
  479.         outchunk[curcount++] = curbyte;
  480.         runcount--;
  481.         }
  482.         if (curcount > 110) {
  483.         iffobyte(curcount - 1);
  484.         for (i = 0; i < curcount; i++)
  485.             iffobyte(outchunk[i]);
  486.         curcount = 0;
  487.         }
  488.     }
  489.     curbyte = b;
  490.     runcount = 1;
  491.     }
  492. }
  493.  
  494. static void 
  495. finishrow(void)
  496. {
  497.     register int i;
  498.  
  499.     if (runcount <= 2) {
  500.     while (runcount > 0) {
  501.         outchunk[curcount++] = curbyte;
  502.         runcount--;
  503.     }
  504.     }
  505.     if (curcount > 0) {
  506.     iffobyte(curcount - 1);
  507.     for (i = 0; i < curcount; i++)
  508.         iffobyte(outchunk[i]);
  509.     curcount = 0;
  510.     }
  511.     if (runcount > 0) {
  512.     iffobyte(256 - runcount + 1);
  513.     iffobyte(curbyte);
  514.     curbyte = -1;
  515.     runcount = 0;
  516.     }
  517. }
  518.  
  519. #define BADFLAGS    (SPRITES|VP_HIDE|GENLOCK_AUDIO|GENLOCK_VIDEO)
  520. #define FLAGMASK    (~BADFLAGS)
  521. #define CAMGMASK    (FLAGMASK & 0x0000FFFFL)
  522.  
  523. /* Routine to write out color bitmap. */
  524. void 
  525. saveiff(void)
  526. {
  527.     long int formlen = 0, formpos, bmhdlen, camglen, camgbod;
  528.     long int bodylen = 0, bodypos, cmaplen;
  529.     long int numcolors, rowlen, rowoff, coloff;
  530.     short int i, j, k;
  531.     UWORD *coltable;
  532.     UBYTE *byteptr, rgb[3];
  533.     struct BitMap *PLBitMap;
  534.     char *filename;
  535.     FILE *IFFFile;
  536.     char *plfilereq();
  537.  
  538.     filename = plfilereq();
  539.     if (!filename)
  540.     return;
  541.  
  542.     if ((IFFFile = fopen(filename, "w+")) == NULL) {
  543.     fprintf(stderr, "Can't open %s\n", filename);
  544.     return;
  545.     }
  546.  
  547.     iffpos = 0;
  548.     curbyte = -1;
  549.     curcount = 0;
  550.     runcount = 0;
  551.     OutFile = IFFFile;
  552.  
  553.     bmhdlen = sizeof(struct BitMapHeader);
  554.     camglen = 4;
  555.     PLBitMap = &PLScreen->BitMap;
  556.  
  557.     fwrite("FORM", sizeof(char), 4, IFFFile);
  558.     formpos = ftell(IFFFile);
  559.     fwrite((char *) &formlen, sizeof(long), 1, IFFFile);
  560.  
  561.     fwrite("ILBM", sizeof(char), 4, IFFFile);
  562.     formlen += 4;
  563.  
  564.     fwrite("BMHD", sizeof(char), 4, IFFFile);
  565.     formlen += 4;
  566.     fwrite((char *) &bmhdlen, sizeof(long), 1, IFFFile);
  567.     formlen += 4;
  568.     bmhd.w = 16 * ((PLWidth + 15) / 16);
  569.     bmhd.h = PLHeight;
  570.     bmhd.x = PLWindow->LeftEdge + XOffset;
  571.     bmhd.y = PLWindow->TopEdge + YOffset;
  572.     bmhd.nPlanes = PLBitMap->Depth;
  573.     bmhd.masking = 0;
  574.     bmhd.compression = 1;
  575.     bmhd.pad1 = 0;
  576.     bmhd.transparentColor = 0;
  577.     bmhd.xAspect = 10;
  578.     bmhd.yAspect = 11;
  579.     bmhd.pageWidth = PLScreen->Width;
  580.     bmhd.pageHeight = PLScreen->Height;
  581.     fwrite((char *) &bmhd, bmhdlen, 1, IFFFile);
  582.     formlen += bmhdlen;
  583.  
  584.     fwrite("CAMG", sizeof(char), 4, IFFFile);
  585.     formlen += 4;
  586.     fwrite((char *) &camglen, sizeof(long), 1, IFFFile);
  587.     formlen += 4;
  588.     camgbod = PLScreen->ViewPort.Modes & CAMGMASK;
  589.     fwrite((char *) &camgbod, sizeof(long), 1, IFFFile);
  590.     formlen += 4;
  591.  
  592.     fwrite("CMAP", sizeof(char), 4, IFFFile);
  593.     formlen += 4;
  594.     numcolors = 1;
  595.     for (i = PLBitMap->Depth; i > 0; i--)
  596.     numcolors *= 2;
  597.     cmaplen = numcolors * 3;
  598.     fwrite((char *) &cmaplen, sizeof(long), 1, IFFFile);
  599.     formlen += 4;
  600.     coltable = (UWORD *) PLCMap->ColorTable;
  601.     for (i = 0; i < numcolors; i++) {
  602.     rgb[0] = (*coltable >> 4) & 0xf0;
  603.     rgb[1] = *coltable & 0xf0;
  604.     rgb[2] = (*coltable << 4) & 0xf0;
  605.     fwrite((char *) rgb, sizeof(UBYTE), 3, IFFFile);
  606.     formlen += 3;
  607.     coltable++;
  608.     }
  609.  
  610.     fwrite("BODY", sizeof(char), 4, IFFFile);
  611.     formlen += 4;
  612.     bodypos = ftell(IFFFile);
  613.     fwrite((char *) &bodylen, sizeof(long), 1, IFFFile);
  614.     formlen += 4;
  615.     rowlen = ((PLWidth + 15) / 16);
  616.     rowlen *= 2;
  617.     rowoff = (PLWindow->TopEdge + YOffset) * PLBitMap->BytesPerRow;
  618.     coloff = (PLWindow->LeftEdge + XOffset) / 8;
  619.     for (i = 0; i < PLHeight; i++) {
  620.     for (j = 0; j < PLBitMap->Depth; j++) {
  621.         byteptr = (UBYTE *) PLBitMap->Planes[j] + rowoff + coloff;
  622.         for (k = 0; k < rowlen; k++)
  623.         iffoutbyte(*byteptr++ & 255);
  624.         finishrow();
  625.     }
  626.     rowoff += PLBitMap->BytesPerRow;
  627.     }
  628.     if (iffpos & 1)
  629.     iffobyte(0);
  630.     bodylen = iffpos;
  631.     formlen += iffpos;
  632.     fflush(IFFFile);
  633.     fseek(IFFFile, formpos, 0);
  634.     fwrite((char *) &formlen, sizeof(long), 1, IFFFile);
  635.     fseek(IFFFile, bodypos, 0);
  636.     fwrite((char *) &bodylen, sizeof(long), 1, IFFFile);
  637.     fclose(IFFFile);
  638. }
  639.  
  640. /*
  641.  *   Code we steal to write a black and white IFF file.
  642.  */
  643. static struct iffhead {
  644.     char formname[4];
  645.     long formlen;        /* fill me in */
  646.     char ilbmname[4];
  647.     char bmhdname[4];
  648.     long bmhdlen;
  649.     short w, h;            /* fill me in */
  650.     long dummy0;
  651.     char numplanes, masking, compression, pad1;
  652.     short tc;
  653.     char xas, yas;
  654.     short pw, ph;
  655.     char cmapname[4];
  656.     long cmaplen;
  657.     char r0, g0, b0, r1, g1, b1;
  658.     char bodyname[4];
  659.     long bodylen;        /* fill me in */
  660. } iffhead = { {'F','O','R','M'}, 0, {'I','L','B','M'}, {'B','M','H','D'}, 20,
  661.       0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 320, 200, {'C','M','A','P'}, 6, 240, 240,
  662.       240, 0, 0, 0, {'B','O','D','Y'}, 0 } ;
  663.  
  664. /*
  665.  *   Finally we get into the nitty gritty of writing the stupid file.
  666.  */
  667.  
  668. void 
  669. iffwritefile(PLINT xdpi, PLINT ydpi, FILE *File)
  670. {
  671.     register int i, j;
  672.     register short *p;
  673.  
  674.     p = bitmap;
  675.     OutFile = File;
  676.     fwrite((char *) &iffhead, 1, sizeof(struct iffhead), OutFile);
  677.     iffpos = 0;
  678.     curbyte = -1;
  679.     curcount = 0;
  680.     runcount = 0;
  681.     for (j = 0; j < bitmapy; j++) {
  682.     for (i = wordsperrow; i; i--, p++) {
  683.         iffoutbyte((*p >> 8) & 255);
  684.         iffoutbyte(*p & 255);
  685.     }
  686.     finishrow();
  687.     }
  688.     if (iffpos & 1)
  689.     iffobyte(0);
  690.     fseek(OutFile, 0L, 0);
  691.     iffhead.w = bitmapx;
  692.     iffhead.h = bitmapy;
  693.     iffhead.pw = bitmapx;
  694.     iffhead.ph = bitmapy;
  695.     iffhead.formlen = iffpos + sizeof(struct iffhead) - 8;
  696.     iffhead.bodylen = iffpos;
  697.     iffhead.xas = xdpi;
  698.     iffhead.yas = ydpi;
  699.     fwrite((char *) &iffhead, 1, sizeof(struct iffhead), OutFile);
  700. }
  701.  
  702. /* Use 1.3 palette program to set colors. */
  703. /* Note this comes with 2.0 as 'sys:tools/colors' */
  704.  
  705. void 
  706. plcolreq(void)
  707. {
  708.     short i;
  709.     extern PLINT MaxColors;
  710.     struct FileLock *lock;
  711.     struct Process *thisproc;
  712.     APTR winptr;
  713.  
  714.     /* This ensures that a requester won't appear if device doesn't exist */
  715.     thisproc = (struct Process *) FindTask(0);
  716.     winptr = thisproc->pr_WindowPtr;
  717.     thisproc->pr_WindowPtr = (APTR) - 1;    /* No window */
  718.  
  719.     /* Check to see if palette is in tools: or sys:tools */
  720.     /* Note this has been renamed to 'sys:tools/colors' in 2.0 */
  721.  
  722.     if (lock = (struct FileLock *) Lock("sys:tools/colors", ACCESS_READ)) {
  723.     Execute("sys:tools/colors", 0, 0);
  724.     UnLock((BPTR) lock);
  725.     }
  726.     else if (lock = (struct FileLock *) Lock("tools:palette", ACCESS_READ)) {
  727.     Execute("tools:palette", 0, 0);
  728.     UnLock((BPTR) lock);
  729.     }
  730.     /* Can't find palette so just return */
  731.     else {
  732.     thisproc->pr_WindowPtr = winptr;
  733.     return;
  734.     }
  735.  
  736.     /* Restore window pointer */
  737.     thisproc->pr_WindowPtr = winptr;
  738.  
  739.     /* Save new colors in PLCurPrefs. */
  740.     for (i = 0; i < MaxColors; i++)
  741.     PLCurPrefs.Color[i] = GetRGB4(PLCMap, i);
  742.  
  743. }
  744.  
  745. /* This routine disables all the gadgets attached to PLWindow.
  746.    It's useful when saving the window as an IFF file or when dumping it
  747.    to the printer. (We don't want the user moving the window around or
  748.    resizing it during those periods.). We always disable the window sizing
  749.    and close gadgets. If flag is zero we disable the dragging gadget also. */
  750.  
  751. void 
  752. disablegads(PLINT flag)
  753. {
  754.     int type;
  755.     struct Gadget *gadget;
  756.  
  757.     gadget = PLWindow->FirstGadget;
  758.     while (gadget) {
  759.     type = gadget->GadgetType & 0x00ff;
  760.     if (type == SIZING || type == CLOSE || (type == WDRAGGING && !flag))
  761.         OffGadget(gadget, PLWindow, 0);
  762.     gadget = gadget->NextGadget;
  763.     }
  764. }
  765.  
  766. void 
  767. enablegads(void)
  768. {
  769.     struct Gadget *gadget;
  770.  
  771.     gadget = PLWindow->FirstGadget;
  772.     while (gadget) {
  773.     OnGadget(gadget, PLWindow, 0);
  774.     gadget = gadget->NextGadget;
  775.     }
  776.     RefreshWindowFrame(PLWindow);
  777. }
  778.